using System;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Text;
using System.Windows.Forms;

using Syncfusion.Windows.Forms.Grid;
using ctsu.BaseForms;
using ctsu.Data;

namespace ctsu.Admin.BusLogic.CoreLab
{

	public class BLCoreLabFormGridNewFromExistingIn : BLCoreLabFormGridBaseImpl
	{
		public BLCoreLabFormGridNewFromExistingIn(FormGridMeta formGridMeta, GridControl grid, FormInfoBase formInfo, Form form)
			: base(formGridMeta, grid, formInfo, form)
		{

		}

		#region initialize
		public override bool Initialize()
		{
			_errorControl = (Label)Forms.Utils.GetControlByName("errCtl", this._form.Controls);
			_btnEditBatch = (Button)Forms.Utils.GetControlByName("btnEditBatch", this._form.Controls);
			_btnRemoveBatch = (Button)Forms.Utils.GetControlByName("btnRemoveBatch", this._form.Controls);
			_btnPrint = (Button)Forms.Utils.GetControlByName("btnPrint", this._form.Controls);
			_btnSave = (Button)Forms.Utils.GetControlByName("btnSave", this._form.Controls);

			StringBuilder sb = new StringBuilder();
			string sql = "SELECT t.ID, 0 AS OrigID, t.DrawSample, d.Protocol, d.Patient, " +
				" t.TestType, t.UnitOfMeasure, t.Location, " +
				" t.SmallNote, t.Note " +
				" FROM TestSamples t,DrawSamples d " +
				" WHERE 1=2 AND d.ID=t.DrawSample";

			try
			{
				this._tableSchema = Forms.Utils.GetTableSchema(null, sql);

				InitializeGridControl();
				return true;
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve grid table schema!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Grid Data Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
		}

		private void InitializeGridControl()
		{
			this._grid.BeginUpdate();
			//this adds up the total column width
			int totColWidth = 0;

			int col = 1;
			//create the new grid columns for drawSamples			
			this._grid.ColCount = this._formGridMeta.GridColumns.Count;
			//start with drawSamples table
			foreach (DataColumn dc in this._tableSchema.Columns)
			{
				//get the metadata for this column
				if (!this._formGridMeta.GridColumns.Contains(dc.ColumnName))
					continue;

				FormGridColumnMeta fgcm = (FormGridColumnMeta)this._formGridMeta.GridColumns[dc.ColumnName];
				//store the dataColum in the tag property
				//in the header row
				this._grid[0, col].Tag = dc;
				this._grid[0, col].Text = fgcm.DisplayName;
				GridStyleInfo gsi = this._grid.ColStyles[col];
				gsi.CellType = fgcm.CellType;
				gsi.Enabled = true;
				//gsi.Text = fgcm.DisplayName;

				if (fgcm.CellType == "CheckBox")
				{
					gsi.CheckBoxOptions = new GridCheckBoxCellInfo("1", "0", "", true);
					gsi.TriState = false;
					gsi.CellValueType = typeof(string);
					gsi.CellValue = "0";

				}
				else
				{
					gsi.CellValue = null;
					gsi.CellValueType = Type.GetType(fgcm.DataType);

					if (fgcm.CellType == "ComboBox")
					{
						BindGridColumn(fgcm, gsi);
						gsi.DropDownStyle = GridDropDownStyle.AutoComplete;
						//gsi.ReadOnly = false;
					}
				}

				this._grid.ColWidths[col] = fgcm.Width;
				totColWidth += fgcm.Width;
				if (fgcm.IsHidden)
					this._grid.Cols.Hidden[col] = true;
				if (fgcm.ReadOnly)
					gsi.ReadOnly = true;
				col++;
			}

			HookGridEvents();

			//			if(totColWidth < MaxWidth)
			//				this._grid.Width = totColWidth + 60;

			this._grid.ResizeRowsBehavior = GridResizeCellsBehavior.None;
			this._grid.Model.RowHeights.ResizeToFit(GridRangeInfo.Row(0), GridResizeToFitOptions.IncludeHeaders);
			this._grid.EndUpdate();
		}
		#endregion initialize

		#region add replace remove
		public override void ReplaceRow(object obj, int row)
		{
			DataRow dr = (DataRow)this._grid[row, 0].Tag;
			Sample samp = (Sample)obj;
			//get the original id
			int origID = (int)this._grid[row, 2].CellValue;

			this._grid.IgnoreReadOnly = true;

			//validate			
			if (samp.TestType != -2)
			{
				this._grid[row, 6].CellValue = samp.TestType;
				AssignChangeToDataRow(row, 6);
			}

			if (samp.UnitOfMeasure != -2)
			{
				this._grid[row, 7].CellValue = samp.UnitOfMeasure;
				AssignChangeToDataRow(row, 7);
			}

			this._grid[row, 8].Text = samp.Location;
			AssignChangeToDataRow(row, 8);

			if (samp.SmallNote.Length > 0)
			{
				this._grid[row, 9].Text = samp.SmallNote.Trim();
				AssignChangeToDataRow(row, 9);
			}

			if (samp.Note.Length > 0)
			{
				this._grid[row, 10].Text = "original id:" + origID.ToString() + " " + samp.Note.Trim();
				AssignChangeToDataRow(row, 10);
			}
			this._grid.IgnoreReadOnly = false;
		}

		public override void AddRow(object obj, int row)
		{
			this._grid.IgnoreReadOnly = true;
			Sample samp = (Sample)obj;
			DataRow dr = _data.NewRow();
			this._data.Rows.Add(dr);

			int rows = ++this._grid.RowCount;

			this._grid[rows, 0].Tag = dr;
			this._grid[rows, 1].Tag = samp;

			this._grid[rows, 1].CellValue = samp.TestID;
			AssignChangeToDataRow(rows, 1);

			this._grid[rows, 2].CellValue = (int)samp.Tag;
			AssignChangeToDataRow(rows, 2);

			this._grid[rows, 3].CellValue = samp.DrawID;
			AssignChangeToDataRow(rows, 3);

			this._grid[rows, 4].CellValue = samp.Protocol;
			this._grid[rows, 4].Tag = samp.ProtocolInfo;
			this._grid[rows, 4].CellTipText = samp.ProtocolInfo.GetToolTip();
			//AssignChangeToDataRow(rows, 4);

			this._grid[rows, 5].CellValue = samp.PatientInfo.GetMrnOrOtherIdentifier();
			this._grid[rows, 5].Tag = samp.PatientInfo;
			this._grid[rows, 5].CellTipText = samp.PatientInfo.GetToolTip();
			//AssignChangeToDataRow(rows, 5);

			this._grid[rows, 6].CellValue = samp.TestType;
			AssignChangeToDataRow(rows, 6);

			this._grid[rows, 7].CellValue = samp.UnitOfMeasure;
			AssignChangeToDataRow(rows, 7);

			this._grid[rows, 8].Text = samp.Location;
			AssignChangeToDataRow(rows, 8);

			this._grid[rows, 9].Text = samp.SmallNote;
			AssignChangeToDataRow(rows, 9);

			this._grid[rows, 10].Text = "original id:" + (int)samp.Tag + samp.Note;
			AssignChangeToDataRow(rows, 10);

			this._grid.IgnoreReadOnly = false;
			this._grid.ScrollCellInView(this._grid.RowCount, 0);
		}
		#endregion add replace remove

		public override void New()
		{
			//just create an empty table where we can add new rows
			string sql = "SELECT t.ID, 0 AS OrigID, t.DrawSample, d.Protocol, d.Patient, " +
				" t.TestType, t.UnitOfMeasure, t.Location, " +
				" t.SmallNote, t.Note " +
				" FROM TestSamples t,DrawSamples d " +
				" WHERE 1=2 AND d.ID=t.DrawSample";

			//SqlConnection conn = LoginForm.GetSqlConnection();
			StringBuilder sb = new StringBuilder();
			try
			{
				DataSet ds = DataAccess.GetDataSet(sql);
				_data = ds.Tables[0];
				this._grid.RowCount = 0;
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve new empty grid table!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Grid Table Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}

		}


		public override bool GetData(int id)
		{
			//there is no edit here so you don't have to requery the data, just dispaly the new ids
			int row = 1;
			foreach (DataRow dr in _data.Rows)
			{
				this._grid[row, 1].CellValue = dr["ID"];
				row++;
			}
			if (this._grid.RowCount > 0)
				this._btnPrint.Enabled = true;
			else
				this._btnPrint.Enabled = false;
			return true;
		}

		#region save
		public override bool Save(int foreignID, out string message, Microsoft.Practices.EnterpriseLibrary.Data.Database db, DbTransaction trans)
		{
			message = "";
			if (_data == null)
				return true;

			foreach (DataRow dr in _data.Rows)
			{
				//do a update for both added (record already exists, it's just being tied to 
				//this check-out batch number) and modified
				if (dr.RowState == DataRowState.Added || dr.RowState == DataRowState.Modified)
				{
					if (!SaveNewRow(dr, foreignID, out message, db, trans))
						return false;
				}
			}
			return true;
		}

		private bool SaveNewRow(DataRow dr, int foreignID, out string message, Microsoft.Practices.EnterpriseLibrary.Data.Database db, DbTransaction trans)
		{
			message = "";

			//sql insert			
			string sqlIns = "INSERT INTO TestSamples (DrawSample,BatchInNum,TestType,UnitOfMeasure, " +
				" Location,SmallNote,Note,IsLegacy) " +
				" VALUES(@DrawSample,@BatchInNum,@TestType,@UnitOfMeasure,@Location,@SmallNote, " +
				" @Note,@IsLegacy)";

			//sql parameters
			SqlParameter[] aParams = new SqlParameter[8];
			aParams[0] = new SqlParameter("@DrawSample", SqlDbType.Int, 0, "DrawSample");
			aParams[1] = new SqlParameter("@BatchInNum", SqlDbType.Int, 0, "BatchInNum");
			aParams[1].Value = foreignID;
			aParams[2] = new SqlParameter("@TestType", SqlDbType.Int, 0, "TestType");
			aParams[3] = new SqlParameter("@UnitOfMeasure", SqlDbType.Int, 0, "UnitOfMeasure");
			aParams[4] = new SqlParameter("@Location", SqlDbType.NVarChar, 50, "Location");
			aParams[5] = new SqlParameter("@SmallNote", SqlDbType.NVarChar, 50, "SmallNote");
			aParams[6] = new SqlParameter("@Note", SqlDbType.NVarChar, 4000, "Note");
			aParams[7] = new SqlParameter("@IsLegacy", SqlDbType.Bit, 0, "IsLegacy");
			aParams[7].Value = 0;

			AssignParameters(aParams, dr, foreignID, 0);
			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sqlIns);
				DataAccess.AddParamArrayToDbCommand(cmd, aParams);

				int i = db.ExecuteNonQuery(cmd, trans);
				//SqlHelper.ExecuteNonQuery(trans, CommandType.Text, sqlIns, aParams);
				//get key id for new row
				//this will assign the new value to the dataRow column
				SetKeyValues(db, trans, dr);
			}
			catch (Exception ex)
			{
				message = ex.Message;
				return false;
			}
			return true;
		}

		private void SetKeyValues(Microsoft.Practices.EnterpriseLibrary.Data.Database db, DbTransaction trans, DataRow dr)
		{
			//TODO - this is setup for autoIncrement keys only
			//need to something if otherwise			

			try
			{
				foreach (DataColumn dc in this._tableSchema.Columns)
				{
					if (dc.AutoIncrement)
					{
						object o = db.ExecuteScalar(trans, CommandType.Text, "SELECT @@IDENTITY");
						dr[dc.ColumnName] = o;
						return;
					}
				}
			}
			catch
			{
			}
		}
		#endregion save


	}
}
